import 'dart:convert';
import 'package:crypto/crypto.dart' as crypto show md5;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_smart_heating/common/event.dart';
import 'package:flutter_smart_heating/common/http.dart';
import 'package:flutter_smart_heating/config/config.dart';
import 'package:flutter_smart_heating/pages/browser/browser.dart';
import 'package:flutter_smart_heating/pages/user/login/login.dart';
import 'package:flutter_smart_heating/service/auth_service.dart';
import 'package:flutter_smart_heating/ui/ui.dart';
import 'package:fluwx/fluwx.dart';
import 'package:get/get.dart';
import 'package:device_info_plus/device_info_plus.dart';

class App {
  /// 页面上报
  static report(path, [params]) {
    Http.instance.post('/plugin/visitor/api/report', data: {
      'path': path,
      'params': params ?? Get.parameters,
    });
  }

  /// 跳转路由
  static push(String url,
      {BuildContext? context,
      Map<String, String>? parameters,
      bool redirect = false,
      String openType = 'navigate'}) async {
    if (url.isEmpty) {
      return false;
    }
    url = url.trim();

    if (url == 'notopen' ||
        url.contains('--notopen--') ||
        url.contains('--notopen.${Http.deviceType}--')) {
      return Ui.toast('该功能暂未开放');
    }

    if (url.startsWith('wechat://')) {
      Fluwx fluwx = Fluwx();
      if (await fluwx.open(target: MiniProgram(username: url.substring(9)))) {
        return true;
      } else {
        return Ui.toast('无法打开该小程序');
      }
    }

    /// 是否要登录才可以打开
    if (url.contains('--token--')) {
      if (!await AuthService.instance.isLoginOrToLogin()) {
        return false;
      }
      //   var token = LocalStorage.instance.getItem<String>('user.token');
      var token = AuthService.instance.sign();
      url = url.replaceAll('--token--', token);
    }

    /// 是否要认证才可以打开
    if (url.contains('--authentication--')) {
      if (!await AuthService.instance.isLoginOrToLogin()) {
        return false;
      }
      if (AuthService.instance.user.isAuthentication != true) {
        return push(
            '/pages/user/profile/authentication/authentication?--token--');
      }
    }

    /// 是否要VIP才可以打开
    if (url.contains('--vip--')) {
      if (!await AuthService.instance.isLoginOrToLogin()) {
        return false;
      }
      if (AuthService.instance.user.isVip != true) {
        return push('/pages/user/vip/vip?--token--');
      }
    }

    if (url.startsWith('/user/logout')) {
      var res = await UiActionSheet.show(
        title: "确定要退出登录吗？",
        items: [UiActionSheetItemData(title: "确定")],
      );

      if (res != null && res != 'canceled') {
        var auth = Get.find<AuthService>();
        await auth.logout();
        await 0.5.delay();
        App.push('/login', redirect: true);

        ///Ui.toast('已退出');
      }
      return true;
    }

    /// 打开远程页面
    if (url.startsWith('http') ||
        url.startsWith('browser://') ||
        openType == 'browser') {
      if (url.startsWith('browser://')) {
        url = url.substring(10);
        if (!url.startsWith('/')) {
          url = '/$url';
        }
        url = '${Config.server}$url';
      } else if (!url.startsWith('http')) {
        url = '${Config.server}$url';
      }

      if (context != null) {
        return await pushRoute(Get.context, BrowserPage(url: url));
      }
      url = "/browser?url=${Uri.encodeComponent(url)}";
    }

    if (url.startsWith('switchTab://') || openType == 'switchTab') {
      url = url.startsWith('switchTab://') ? url.substring(11) : url;

      backHome();
      return AppEvent()
          .eventBus
          .fire(RootSetCurrentTabIndexEvent(Uri.parse(url)));
    }

    if (!isAppRoute(url)) {
      url = '/404';
    }

    if (url.contains('--redirect--') || redirect) {
      return Get.offNamed(
        url,
        parameters: parameters,
        preventDuplicates: false,
      );
    }

    return Get.toNamed(url, parameters: parameters);
  }

  static bool isAppRoute(url) {
    return Get.routeTree.matchRoute(url).route?.name != '/';
  }

  /// 打开页面
  static Future pushRoute(
    context,
    widget, {
    bool maintainState = true,
    bool fullscreenDialog = false,
  }) async {
    return Navigator.of(context).push(
      CupertinoPageRoute(
        fullscreenDialog: fullscreenDialog,
        maintainState: maintainState,
        builder: (context) {
          return widget;
        },
      ),
    );
  }

  /// 返回上一页面
  static back<T>(context, {T? result}) {
    if (Navigator.of(context).canPop()) {
      Navigator.of(context).pop(result);
    }
  }

  /// 打开登录页
  static pushLogin() async {
    await pushRoute(
      Get.context,
      const LoginPage(),
      fullscreenDialog: true,
    );
  }

  /// 点击震动回馈
  static hapticFeedback({int level = 0}) {
    //HapticFeedback.vibrate();
    switch (level) {
      case 0:
        HapticFeedback.selectionClick();
        break;
      case 1:
        HapticFeedback.lightImpact();
        break;
      case 2:
        HapticFeedback.mediumImpact();
        break;
      case 3:
        HapticFeedback.heavyImpact();
        break;
      case 4:
        HapticFeedback.vibrate();
        break;
    }
  }

  ///返回首页
  static backHome() {
    return Get.until(
      (route) =>
          Get.currentRoute.split('?').first ==
          (AuthService.instance.isLogined ? '/' : '/splash'),
    );
  }

  static String md5(String str) {
    Uint8List content = const Utf8Encoder().convert(str);
    return crypto.md5.convert(content).toString();
  }

  /// Color转换MaterialColor
  static MaterialColor createMaterialColor(Color color) {
    List strengths = <double>[.05];
    Map swatch = <int, Color>{};
    final int r = color.red, g = color.green, b = color.blue;

    for (int i = 1; i < 10; i++) {
      strengths.add(0.1 * i);
    }
    for (var strength in strengths) {
      final double ds = 0.5 - strength;
      swatch[(strength * 1000).round()] = Color.fromRGBO(
        r + ((ds < 0 ? r : (255 - r)) * ds).round(),
        g + ((ds < 0 ? g : (255 - g)) * ds).round(),
        b + ((ds < 0 ? b : (255 - b)) * ds).round(),
        1,
      );
    }
    return MaterialColor(color.value, swatch as Map<int, Color>);
  }

  static Future<String?> getDeviceId() async {
    String? deviceId;
    DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
    if (GetPlatform.isAndroid) {
      AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
      deviceId = androidInfo.id;
    } else if (GetPlatform.isIOS) {
      IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
      deviceId = iosInfo.identifierForVendor;
    }
    return deviceId;
  }
}
